﻿
using Engine;
using Game;
using Mekiasm.Common;
using static Mekiasm.MekCraftingRecipe;

namespace Mekiasm
{
    public class Configurator : ItemFlat,Interface.IChargeAbleItem
    {
        public static int Index;

        public static int MType = 0;

        public ComponentEnergyMachine.FuelType ChargeFuelType => ComponentEnergyMachine.FuelType.Electric;

        public long MaxAmount => GetMaxPower();

        public Configurator() : base("调整器", MekiasmInit.GetFlatTexture(MekiasmInit.R2, "调整器"))
        {                        
        }

        public override bool OnUse(Ray3 aim, ComponentMiner componentMiner, TerrainRaycastResult? raycast)
        {
            if (GetCurrentAmount(componentMiner.ActiveBlockValue) < 4)
            {
                DisplayMsg(componentMiner.ComponentPlayer, "请充电");
                return true;
            }
            SetCurrentAmount(componentMiner.ActiveBlockValue, 0, -4);
            if (raycast.HasValue)
            {
                ComponentBlockEntity blockEntity = ILibrary.SubsystemBlockEntities.GetBlockEntity(raycast.Value.CellFace.X, raycast.Value.CellFace.Y, raycast.Value.CellFace.Z);
                if (blockEntity != null)
                {
                    ComponentEnergyMachine machine = blockEntity.Entity.FindComponent<ComponentEnergyMachine>();
                    machine.MachineFaceConfig.TryGetValue(raycast.Value.CellFace.Face, out MachineFaceConfig config);
                    if (config != null)
                    {
                        if (MType>0)
                        {
                            MekBlock.DeviceType endType = (MekBlock.DeviceType)MType;
                            switch (config.DeviceType)
                            {
                                case MekBlock.DeviceType.Electric:
                                    if (!machine.AllowChangeElectricMode || endType != MekBlock.DeviceType.Electric)
                                    {
                                        DisplayMsg(componentMiner.ComponentPlayer, "禁止修改" + GetConfigName((int)endType)); return true;
                                    }
                                    else break;
                                case MekBlock.DeviceType.Fluid:
                                    if (!machine.AllowChangeFluidMode || endType != MekBlock.DeviceType.Fluid)
                                    {
                                        DisplayMsg(componentMiner.ComponentPlayer, "禁止修改" + GetConfigName((int)endType)); return true;
                                    }
                                    else break;
                                case MekBlock.DeviceType.Item:
                                    if (!machine.AllowChangeItemMode || endType != MekBlock.DeviceType.Item)
                                    {
                                        DisplayMsg(componentMiner.ComponentPlayer, "禁止修改" + GetConfigName((int)endType)); return true;
                                    }
                                    else break;
                                case MekBlock.DeviceType.Gas:
                                    if (!machine.AllowChangeGasMode || endType != MekBlock.DeviceType.Gas)
                                    {
                                        DisplayMsg(componentMiner.ComponentPlayer, "禁止修改" + GetConfigName((int)endType)); return true;
                                    }
                                    else break;
                                default: DisplayMsg(componentMiner.ComponentPlayer, "禁止修改" + GetConfigName((int)endType)); return true;
                            }

                            if (config.MachineMode == MekBlock.MachineMode.IN)
                            {
                                config.MachineMode = MekBlock.MachineMode.OUT;
                                config.DeviceType = (MekBlock.DeviceType)MType;
                                DisplayMsg(componentMiner.ComponentPlayer, "输出模式");
                            }
                            else
                            {
                                config.DeviceType = (MekBlock.DeviceType)MType;
                                config.MachineMode = MekBlock.MachineMode.IN;
                                DisplayMsg(componentMiner.ComponentPlayer, "输入模式");
                            }

                        }
                        else
                        {
                            int v = ILibrary.SubsystemTerrain.Terrain.GetCellValueFast(raycast.Value.CellFace.X, raycast.Value.CellFace.Y, raycast.Value.CellFace.Z);
                            int Id = Terrain.ExtractContents(v);
                            int Data = Terrain.ExtractData(v);
                            if (MekiasmInit.MekBlocks.TryGetValue(Id, out MekBlock mekBlock))
                            {
                                Item item = mekBlock.GetItem(ref v);
                                if (item is ComplexModelItem || item is MachineRotateAbleItem)
                                {
                                    ILibrary.SubsystemTerrain.ChangeCell(raycast.Value.CellFace.X, raycast.Value.CellFace.Y, raycast.Value.CellFace.Z, ILibrary.setDirection(v, (ILibrary.GetDirection(v) + 1) & 0x3));
                                }
                                else
                                {
                                    DisplayMsg(componentMiner.ComponentPlayer, "不支持该方块旋转");
                                }
                            }
                            else
                            {
                                switch (Id)
                                {
                                    case FurnaceBlock.Index:
                                        ILibrary.SubsystemTerrain.ChangeCell(raycast.Value.CellFace.X, raycast.Value.CellFace.Y, raycast.Value.CellFace.Z, Terrain.ReplaceData(Terrain.ReplaceContents(0, 64), (Data + 1) & 0x3));
                                        break;
                                    case FurnitureBlock.Index:
                                        int r = FurnitureBlock.GetRotation(v);
                                        r = FurnitureBlock.SetRotation(Data, r + 1);
                                        ILibrary.SubsystemTerrain.ChangeCell(raycast.Value.CellFace.X, raycast.Value.CellFace.Y, raycast.Value.CellFace.Z, Terrain.ReplaceData(v, r));
                                        break;
                                    default:
                                        DisplayMsg(componentMiner.ComponentPlayer, "不支持该方块旋转");
                                        break;
                                }

                            }
                        }
                    }
                }

            }

            return true;
        }

        public override bool HasExtraSet(int value)
        {
            return true;
        }
        public override void ClickExtraSet(ComponentPlayer player, int value)
        {
            MType++;
            if (MType > 4) MType = 0;
            DisplayMsg(player, GetConfigName(MType));
        }

        public string GetConfigName(int t) {
            switch (t)
            {
                case 1:
                    return "电力模式";
                case 2:
                    return "流体模式";
                case 3:
                    return "气体模式";
                case 4:
                    return "物品模式";
                case 0:
                    return "旋转模式";
            }
            return string.Empty;

        }

        public override int GetMaxPower()
        {
            return 10240;
        }

        public override float GetBlockHealth(int value)
        {
            SaveItemSystem.GetBlockData(value, out var d);
            if (d == null) return -1f;
            else return GetCurrentAmount(value) / (float)GetMaxPower();
        }

        public long GetCurrentAmount(int value)
        {
            SaveItemSystem.GetBlockData(value, out var d);
            if (d == null) return 0;
            else return d.fuelAmount;
        }

        public int SetCurrentAmount(int value, int fuelValue, long varAmount)
        {
            return SaveItemSystem.ChangePower(value, varAmount, fuelValue);
        }


        public int GetChargeFuelValue(int value)
        {
            return 0;
        }

        public bool CanAcceptFuel(int value)
        {
            return true;
        }
    }
}
